home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 285_02 / hoc3.y < prev    next >
Text File  |  1990-07-08  |  4KB  |  174 lines

  1. %{
  2.  
  3. /*
  4. **    HOC3 calculator from "Unix Programming Environment",
  5. **            p247, ch8, by Kernighan & Pike
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <memory.h>                    /* TURBO-C requires MEM.H */
  12. #include <signal.h>
  13. #include <setjmp.h>
  14.  
  15. #include "hocdecl.h"                /* data declarations, function prototypes */
  16.  
  17. %}
  18.  
  19. %union {                /* stack object type    */
  20.     double  val ;       /* actual value         */
  21.     Symbol  *sym ;      /* symbol table ptr     */
  22. }
  23.  
  24. %token  <val>   NUMBER
  25. %token  <sym>   VAR BLTIN UNDEF
  26. %type   <val>   expr asgn
  27. %right  '='
  28. %left   '+' '-'
  29. %left   '*' '/'
  30. %left   UNARYMINUS
  31. %right  '^'         /*  exponentiation */
  32.  
  33. %%
  34.  
  35. list:        /* nothing */
  36.         |   list '\n'
  37.         |   list asgn '\n'
  38.         |   list expr '\n'      { printf("\t%.8g\n", $2) ; }
  39.         |   list error '\n'     { yyerrok ; }
  40.         ;
  41.  
  42. asgn:        VAR '=' expr        { $$ = $1->u.val = $3 ; $1->type = VAR ; }
  43.         ;
  44. expr:       NUMBER
  45.         |   VAR             { if ($1->type == UNDEF)
  46.                                 execerror("undefined variable", $1->name) ;
  47.                             $$ = $1->u.val ; }
  48.         |   asgn
  49.         |   BLTIN '(' expr ')'  { $$ = (*($1->u.ptr))($3) ; }
  50.         |   expr '+' expr   { $$ = $1 + $3 ; }
  51.         |   expr '-' expr   { $$ = $1 - $3 ; }
  52.         |   expr '*' expr   { $$ = $1 * $3 ; }
  53.         |   expr '/' expr   {
  54.                 if ($3 == 0.0)
  55.                     execerror("division by zero", "") ;
  56.                 $$ = $1 / $3 ; }
  57.         |   expr '^' expr   { $$ = Pow( $1, $3) ; }
  58.         |   '(' expr ')'    { $$ = $2 ; }
  59.         |   '-' expr        %prec UNARYMINUS { $$ = -$2 ; }
  60.         ;
  61.  
  62. %%
  63.  
  64. char *progname ;
  65. int lineno = 0 ;
  66. jmp_buf begin ;
  67.  
  68. /*----------------------------------------------------------------------------
  69. **  MAIN     (hoc3.y)
  70. */
  71. int main( char *argv[])
  72. {
  73.     progname = argv[0] ;
  74.     init() ;
  75.     setjmp(begin) ;
  76.     signal( SIGFPE, fpecatch) ;                /* Turbo-C uses "ssignal()" */
  77.     yyparse() ;
  78.  
  79.     return 0 ;
  80. }
  81.  
  82. /*----------------------------------------------------------------------------
  83. **  YYLEX
  84. **   lexical analyser function
  85. */
  86. int yylex( void)
  87. {
  88.  int c ;
  89.  char sbuf[100], *p ;
  90.  Symbol *s ;
  91.  
  92.     p = &sbuf[0] ;
  93.  
  94.     while ((c = getchar()) == ' ' || c == '\t')
  95.         ;
  96.  
  97.     if (c == EOF)
  98.         return 0 ;
  99.  
  100.     if (c == '.' || isdigit(c))
  101.     {
  102.         ungetc( c, stdin) ;
  103.         scanf("%lf", &yylval.val) ;
  104.         return NUMBER ; 
  105.     }
  106.  
  107.     if (isalpha(c))
  108.     {
  109.         do{
  110.             *p++ = (char) c ;
  111.         } while ((c = getchar()) != EOF && isalnum(c)) ;
  112.  
  113.         ungetc( c, stdin) ;
  114.         *p = '\0' ;
  115.  
  116.         if ((s = lookup(&sbuf[0])) == 0)
  117.             s = install( sbuf, UNDEF, 0.0) ;
  118.  
  119.         yylval.sym = s ;
  120.  
  121.         return ((s->type == UNDEF) ? (VAR) : (s->type)) ;
  122.     }
  123.  
  124.     if (c == '\n')
  125.         lineno++ ;
  126.  
  127.     return c ;
  128. }
  129.  
  130. /*----------------------------------------------------------------------------
  131. **  EXECERROR
  132. */
  133. void execerror( char *s, char *t)
  134. {
  135.     warning( s, t) ;
  136.     longjmp( begin, 0) ;
  137. }
  138.  
  139. /*----------------------------------------------------------------------------
  140. **  FPECATCH
  141. */
  142. void fpecatch( void)
  143. {
  144.     execerror("floating point exception", (char *) 0) ;
  145. }
  146.  
  147.  
  148. /*----------------------------------------------------------------------------
  149. **  YYERROR
  150. */
  151. void yyerror( char *s)                  /* called by yacc syntax error */
  152. {
  153.     warning( s, (char *) 0) ;
  154. }
  155.  
  156. /*----------------------------------------------------------------------------
  157. **  WARNING
  158. */
  159. void warning( char *s, char *t)
  160. {
  161.     fprintf( stderr, "%s: %s", progname, s) ;
  162.  
  163.     if (t)
  164.         fprintf( stderr, " %s", t) ;
  165.  
  166.     fprintf( stderr, " near line %d\n", lineno) ;
  167. }
  168.  
  169.  
  170. /*--------------------------------------------------------------------------*/
  171. /*--------------------------------------------------------------------------*/
  172. /*--------------------------------------------------------------------------*/
  173.  
  174.